#include <string.h>
#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base(const char *pbase)
    : _pbase(new char[strlen(pbase) + 1]())
    {
        cout << "Base(const char *)" << endl;
        strcpy(_pbase, pbase);
    }

    virtual
    void print() const
    {
        if(_pbase)
        {
            cout << "Base::_pbase = " << _pbase << endl;
        }
    }

    //将基类的析构函数设置为虚函数之后，派生类的析构函数会自动
    //变为虚函数
    //
    //析构函数对于每一个类而言，具有唯一性（析构函数没有返回
    //类型，没有参数列表）
    //对于编译器而言，析构函数只有一个，所以就可以写为
    //destructor,如果将基类的析构函数设置为虚函数，只要派生类
    //将析构函数实现出来，对于编译器而言就可以认为是重写
    //唯一的一个名字不一样的重写（靠的是析构函数的唯一性的
    //特点，靠的是编译器的名字的改变）
    virtual
    ~Base()
    {
        cout << "~Base()" << endl;
        if(_pbase)
        {
            delete [] _pbase;
            _pbase = nullptr;
        }
    }
private:
    char *_pbase;
};

class Derived
:public Base
{
public:
    Derived(const char *pbase, const char *pderived)
    : Base(pbase)
    , _pderived(new char[strlen(pderived) + 1]())
    {
        cout << "Derived(const char *, const char *)" << endl;
        strcpy(_pderived, pderived);
    }

    void print() const override
    {
        if(_pderived)
        {
            cout << "Derived::_pderived = " << _pderived << endl;
        }
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
        if(_pderived)
        {
            delete [] _pderived;
            _pderived = nullptr;
        }
    }
private:
    char *_pderived;
};


int main(int argc, char *argv[])
{
    Base *pbase = new Derived("hello", "world");//堆对象
    pbase->print();

    //delete表达式的工作步骤
    //1、调用析构函数  pbase->~Base(),pbase->~destructor();
    //2、调用operator delete
    delete pbase;//pbase->~Derived()
    /* delete dynamic_cast<Derived *>(pbase); */
    pbase = nullptr;

    return 0;
}

